package game.entity.ui;

import game.entity.EntityGroup_I;
import game.entity.Entity_A;
import game.entity.process.EntityProcessor_I;
import game.entity.process.ThinkProcess;
import game.entity.process.UpdateProcess;
import game.gamestate.GameState;

import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;

import common.Log;

public class UI_Group implements EntityGroup_I<UI_Entity> {
	
	public UI_Group() {
		_Entities = new ArrayList<UI_Entity>(32);
		_SpawnList = new LinkedList<UI_Entity>();
		_DestroyList = new LinkedList<UI_Entity>();

		initializeProcesses();
	}
	
	private void initializeProcesses() {
		_Processors = new LinkedList<EntityProcessor_I<UI_Entity>>();
		_Processors.add(new ThinkProcess<UI_Entity>());
		_Processors.add(new UpdateProcess<UI_Entity>());
	}
	
	private List<EntityProcessor_I<UI_Entity>> _Processors;

	private ArrayList<UI_Entity> _Entities;
	private LinkedList<UI_Entity> _SpawnList;
	private LinkedList<UI_Entity> _DestroyList;
	
	@Override
	public void spawn(UI_Entity ui, GameState gameState) {
		if(ui == null) {
			Log.debug("Null entity ignored.", this);
			return;
		}
		
		if(_Entities.contains(ui) == true || _SpawnList.contains(ui)) {
			Log.debug("Attempted to spawn another copy of " + ui.Name +". Rejected.", this);
			return;
		}
		_SpawnList.push(ui);
	}
	
	@Override
	public void destroy(UI_Entity ui, GameState gameState) {
		if(ui == null) {
			if(ui == null) {
				Log.debug("Null entity ignored.", this);
				return;
			}
		}
		if(_Entities.contains(ui) == false || _DestroyList.contains(ui) == true) {
			Log.debug("Attempted to remove a non-existing instance of " + ui.Name +". Rejected.", this);
			return;
		}
		ui.destroy(gameState);
		_DestroyList.push(ui);
	}
	@Override
	public void destroyAll(GameState gameState) {
		for(UI_Entity ui : _Entities) {
			ui.destroy(gameState);
			_DestroyList.push(ui);
		}
	}
	
	@Override
	public void process(GameState gameState, int elapsed) {
		// spawn all entities waiting to get into the game.
		for(UI_Entity ui : _SpawnList) {
			_Entities.add(ui);
			ui.create(gameState);
		}
		_SpawnList.clear();
		
		// process all ui entities.
		for(EntityProcessor_I<UI_Entity> processor : _Processors) {
			processor.process(_Entities, gameState, elapsed);
		}
		
		// remove all entities listed in the destroy list.
		for(UI_Entity ui : _DestroyList) {
			_Entities.remove(ui);
		}
		_DestroyList.clear();
	}
	@Override
	public List<UI_Entity> getEntities() {
		return _Entities;
	}
}